{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import pandas as pd\n",
    "\n",
    "\n",
    "df = pd.read_csv(os.path.join(\"data\", \"highlight_flight_trajectories.csv\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us take a glance at the data.\n",
    "Each row represents the trajectory of a flight,\n",
    "and the last column contains the coordinates of the flight path in `GeoJSON` format."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Unnamed: 0</th>\n",
       "      <th>dep</th>\n",
       "      <th>dest</th>\n",
       "      <th>geojson</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>Place_MontpellierMediterranee_Airport</td>\n",
       "      <td>Place_BastiaPoretta_Airport</td>\n",
       "      <td>{\"type\": \"LineString\", \"coordinates\": [[3.9613...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>Place_Bristol___Lulsgate</td>\n",
       "      <td>Place_TenerifeSur_ReinaSofia_Airport</td>\n",
       "      <td>{\"type\": \"LineString\", \"coordinates\": [[-2.719...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>Place_Valencia_Manises_Airport</td>\n",
       "      <td>Place_Bucuresti_HenriCoanda_Airport</td>\n",
       "      <td>{\"type\": \"LineString\", \"coordinates\": [[-0.481...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Unnamed: 0                                    dep  \\\n",
       "0           0  Place_MontpellierMediterranee_Airport   \n",
       "1           1               Place_Bristol___Lulsgate   \n",
       "2           2         Place_Valencia_Manises_Airport   \n",
       "\n",
       "                                   dest  \\\n",
       "0           Place_BastiaPoretta_Airport   \n",
       "1  Place_TenerifeSur_ReinaSofia_Airport   \n",
       "2   Place_Bucuresti_HenriCoanda_Airport   \n",
       "\n",
       "                                             geojson  \n",
       "0  {\"type\": \"LineString\", \"coordinates\": [[3.9613...  \n",
       "1  {\"type\": \"LineString\", \"coordinates\": [[-2.719...  \n",
       "2  {\"type\": \"LineString\", \"coordinates\": [[-0.481...  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><span style=\"color:#565656\">Make this Notebook Trusted to load map: File -> Trust Notebook</span><iframe src=\"about:blank\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" data-html=PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgCiAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICAgTF9OT19UT1VDSCA9IGZhbHNlOwogICAgICAgICAgICBMX0RJU0FCTEVfM0QgPSBmYWxzZTsKICAgICAgICA8L3NjcmlwdD4KICAgIAogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS42LjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NvZGUuanF1ZXJ5LmNvbS9qcXVlcnktMS4xMi40Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS42LjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L2doL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9mb2xpdW0vdGVtcGxhdGVzL2xlYWZsZXQuYXdlc29tZS5yb3RhdGUubWluLmNzcyIvPgogICAgCiAgICAgICAgICAgIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsCiAgICAgICAgICAgICAgICBpbml0aWFsLXNjYWxlPTEuMCwgbWF4aW11bS1zY2FsZT0xLjAsIHVzZXItc2NhbGFibGU9bm8iIC8+CiAgICAgICAgICAgIDxzdHlsZT4KICAgICAgICAgICAgICAgICNtYXBfZDA3Yjk2ODIyMWRiNDQ1Yzk2NmNjZjZmOGJkNGE0ZTQgewogICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgICAgICB3aWR0aDogMTAwLjAlOwogICAgICAgICAgICAgICAgICAgIGhlaWdodDogMTAwLjAlOwogICAgICAgICAgICAgICAgICAgIGxlZnQ6IDAuMCU7CiAgICAgICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwX2QwN2I5NjgyMjFkYjQ0NWM5NjZjY2Y2ZjhiZDRhNGU0IiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKICAgICAgICAgICAgdmFyIG1hcF9kMDdiOTY4MjIxZGI0NDVjOTY2Y2NmNmY4YmQ0YTRlNCA9IEwubWFwKAogICAgICAgICAgICAgICAgIm1hcF9kMDdiOTY4MjIxZGI0NDVjOTY2Y2NmNmY4YmQ0YTRlNCIsCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2VudGVyOiBbNDAuMCwgMTAuMF0sCiAgICAgICAgICAgICAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NywKICAgICAgICAgICAgICAgICAgICB6b29tOiA0LAogICAgICAgICAgICAgICAgICAgIHpvb21Db250cm9sOiB0cnVlLAogICAgICAgICAgICAgICAgICAgIHByZWZlckNhbnZhczogdHJ1ZSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKTsKICAgICAgICAgICAgTC5jb250cm9sLnNjYWxlKCkuYWRkVG8obWFwX2QwN2I5NjgyMjFkYjQ0NWM5NjZjY2Y2ZjhiZDRhNGU0KTsKCiAgICAgICAgICAgIAoKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgdGlsZV9sYXllcl81MWFiZTY3MzBmMWE0ZWRmOTYxNTU5YjNlMjc2NTJmYiA9IEwudGlsZUxheWVyKAogICAgICAgICAgICAgICAgImh0dHBzOi8ve3N9LnRpbGUub3BlbnN0cmVldG1hcC5vcmcve3p9L3t4fS97eX0ucG5nIiwKICAgICAgICAgICAgICAgIHsiYXR0cmlidXRpb24iOiAiRGF0YSBieSBcdTAwMjZjb3B5OyBcdTAwM2NhIGhyZWY9XCJodHRwOi8vb3BlbnN0cmVldG1hcC5vcmdcIlx1MDAzZU9wZW5TdHJlZXRNYXBcdTAwM2MvYVx1MDAzZSwgdW5kZXIgXHUwMDNjYSBocmVmPVwiaHR0cDovL3d3dy5vcGVuc3RyZWV0bWFwLm9yZy9jb3B5cmlnaHRcIlx1MDAzZU9EYkxcdTAwM2MvYVx1MDAzZS4iLCAiZGV0ZWN0UmV0aW5hIjogZmFsc2UsICJtYXhOYXRpdmVab29tIjogMTgsICJtYXhab29tIjogMTgsICJtaW5ab29tIjogMCwgIm5vV3JhcCI6IGZhbHNlLCAib3BhY2l0eSI6IDEsICJzdWJkb21haW5zIjogImFiYyIsICJ0bXMiOiBmYWxzZX0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZDA3Yjk2ODIyMWRiNDQ1Yzk2NmNjZjZmOGJkNGE0ZTQpOwogICAgICAgIAogICAgCiAgICAgICAgZnVuY3Rpb24gZ2VvX2pzb25fZjYxNGE3NzhjOGVlNGYwNWJiNGI1ZTQ4NTUzMTRkY2Rfc3R5bGVyKGZlYXR1cmUpIHsKICAgICAgICAgICAgc3dpdGNoKGZlYXR1cmUuaWQpIHsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiAiNSwgNSIsICJmaWxsQ29sb3IiOiAiI2ZmYWYwMCIsICJ3ZWlnaHQiOiAxLjV9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGdlb19qc29uX2Y2MTRhNzc4YzhlZTRmMDViYjRiNWU0ODU1MzE0ZGNkX2hpZ2hsaWdodGVyKGZlYXR1cmUpIHsKICAgICAgICAgICAgc3dpdGNoKGZlYXR1cmUuaWQpIHsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsiY29sb3IiOiAiZ3JlZW4iLCAiZGFzaEFycmF5IjogIjUsIDUiLCAiZmlsbENvbG9yIjogIiNmZmFmMDAiLCAid2VpZ2h0IjogM307CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gZ2VvX2pzb25fZjYxNGE3NzhjOGVlNGYwNWJiNGI1ZTQ4NTUzMTRkY2Rfb25FYWNoRmVhdHVyZShmZWF0dXJlLCBsYXllcikgewogICAgICAgICAgICBsYXllci5vbih7CiAgICAgICAgICAgICAgICBtb3VzZW91dDogZnVuY3Rpb24oZSkgewogICAgICAgICAgICAgICAgICAgIGdlb19qc29uX2Y2MTRhNzc4YzhlZTRmMDViYjRiNWU0ODU1MzE0ZGNkLnJlc2V0U3R5bGUoZS50YXJnZXQpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG1vdXNlb3ZlcjogZnVuY3Rpb24oZSkgewogICAgICAgICAgICAgICAgICAgIGUudGFyZ2V0LnNldFN0eWxlKGdlb19qc29uX2Y2MTRhNzc4YzhlZTRmMDViYjRiNWU0ODU1MzE0ZGNkX2hpZ2hsaWdodGVyKGUudGFyZ2V0LmZlYXR1cmUpKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIH0pOwogICAgICAgIH07CiAgICAgICAgdmFyIGdlb19qc29uX2Y2MTRhNzc4YzhlZTRmMDViYjRiNWU0ODU1MzE0ZGNkID0gTC5nZW9Kc29uKG51bGwsIHsKICAgICAgICAgICAgICAgIG9uRWFjaEZlYXR1cmU6IGdlb19qc29uX2Y2MTRhNzc4YzhlZTRmMDViYjRiNWU0ODU1MzE0ZGNkX29uRWFjaEZlYXR1cmUsCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgc3R5bGU6IGdlb19qc29uX2Y2MTRhNzc4YzhlZTRmMDViYjRiNWU0ODU1MzE0ZGNkX3N0eWxlciwKICAgICAgICB9KTsKCiAgICAgICAgZnVuY3Rpb24gZ2VvX2pzb25fZjYxNGE3NzhjOGVlNGYwNWJiNGI1ZTQ4NTUzMTRkY2RfYWRkIChkYXRhKSB7CiAgICAgICAgICAgIGdlb19qc29uX2Y2MTRhNzc4YzhlZTRmMDViYjRiNWU0ODU1MzE0ZGNkCiAgICAgICAgICAgICAgICAuYWRkRGF0YShkYXRhKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF9kMDdiOTY4MjIxZGI0NDVjOTY2Y2NmNmY4YmQ0YTRlNCk7CiAgICAgICAgfQogICAgICAgICAgICBnZW9fanNvbl9mNjE0YTc3OGM4ZWU0ZjA1YmI0YjVlNDg1NTMxNGRjZF9hZGQoeyJmZWF0dXJlcyI6IFt7Imdlb21ldHJ5IjogeyJjb29yZGluYXRlcyI6IFtbMy45NjEzODksIDQzLjU4MzMzM10sIFszLjk2ODA1NiwgNDMuNTgwODMzXSwgWzMuOTc0NzIyLCA0My41NzgzMzNdLCBbMy45ODYzODksIDQzLjU3NTI3OF0sIFszLjk5ODMzMywgNDMuNTcyNV0sIFs0LjE2MzMzMywgNDMuNTMwNTU2XSwgWzQuMjY5MTY3LCA0My41MDM4ODldLCBbNC4zOTg4ODksIDQzLjQ3MTExMV0sIFs0LjU0MDI3OCwgNDMuNDM1Mjc4XSwgWzQuNzE2OTQ0LCA0My4zOTA1NTZdLCBbNC45MTcyMjIsIDQzLjM0XSwgWzQuOTI4ODg5LCA0My4zMzY5NDRdLCBbNS4xNTk3MjIsIDQzLjI3NjY2N10sIFs1LjMzMzA1NiwgNDMuMjMxNjY3XSwgWzUuNzI5NzIyLCA0My4yMjkxNjddLCBbNS44Mjg4ODksIDQzLjIyODYxMV0sIFs2LjAyMzg4OSwgNDMuMjI2NjY3XSwgWzYuNjAxOTQ0LCA0My4yMTk0NDRdLCBbNi44NDE2NjcsIDQzLjM0NjExMV0sIFs2Ljg5MzMzMywgNDMuMzczMzMzXSwgWzcuMzYyNSwgNDMuMzI3Nzc4XSwgWzcuNjIxMzg5LCA0My4zMDE5NDRdLCBbOC4zMDMwNTYsIDQzLjE3MDgzM10sIFs4LjQzNDcyMiwgNDMuMTQ1NTU2XSwgWzguNjI2OTQ0LCA0My4xMTgzMzNdLCBbOC43NTkxNjcsIDQzLjA5OTcyMl0sIFs5LjA1OTQ0NCwgNDMuMDU3MjIyXSwgWzkuMDgzMzMzLCA0My4wNTM4ODldLCBbOS4zOTU1NTYsIDQyLjk3ODMzM10sIFs5LjQ4ODMzMywgNDIuOTU1ODMzXSwgWzkuNjAzODg5LCA0Mi45Mjc3NzhdLCBbOS41NzQ0NDQsIDQyLjg0NzIyMl0sIFs5LjU2ODA1NiwgNDIuODI5NDQ0XSwgWzkuNTQyMjIyLCA0Mi43NTg4ODldLCBbOS41MjYxMTEsIDQyLjcxNDcyMl0sIFs5LjUxMzMzMywgNDIuNjc5NDQ0XSwgWzkuNTA2OTQ0LCA0Mi42NjE5NDRdLCBbOS40NzQ3MjIsIDQyLjU3MzYxMV0sIFs5LjQ4NDcyMiwgNDIuNTVdXSwgInR5cGUiOiAiTGluZVN0cmluZyJ9LCAiaWQiOiAiMCIsICJ0eXBlIjogIkZlYXR1cmUifV0sICJ0eXBlIjogIkZlYXR1cmVDb2xsZWN0aW9uIn0pOwoKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF85Y2RiNzE2OTEwMjg0NzRlYTc3M2FlNjkzNmEwM2U5ZSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZGZiM2MxNDhkNjk2NDUwZDhiNTQ2NDkzMmY1ZGUyYmYgPSAkKGA8ZGl2IGlkPSJodG1sX2RmYjNjMTQ4ZDY5NjQ1MGQ4YjU0NjQ5MzJmNWRlMmJmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QbGFjZV9Nb250cGVsbGllck1lZGl0ZXJyYW5lZV9BaXJwb3J0IFBsYWNlX0Jhc3RpYVBvcmV0dGFfQWlycG9ydDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85Y2RiNzE2OTEwMjg0NzRlYTc3M2FlNjkzNmEwM2U5ZS5zZXRDb250ZW50KGh0bWxfZGZiM2MxNDhkNjk2NDUwZDhiNTQ2NDkzMmY1ZGUyYmYpOwogICAgICAgIAoKICAgICAgICBnZW9fanNvbl9mNjE0YTc3OGM4ZWU0ZjA1YmI0YjVlNDg1NTMxNGRjZC5iaW5kUG9wdXAocG9wdXBfOWNkYjcxNjkxMDI4NDc0ZWE3NzNhZTY5MzZhMDNlOWUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgZnVuY3Rpb24gZ2VvX2pzb25fYTBjYTA0OTM2MzJjNDljNmEwYjkxOWUyZjg3YTk2NDNfc3R5bGVyKGZlYXR1cmUpIHsKICAgICAgICAgICAgc3dpdGNoKGZlYXR1cmUuaWQpIHsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiAiNSwgNSIsICJmaWxsQ29sb3IiOiAiI2ZmYWYwMCIsICJ3ZWlnaHQiOiAxLjV9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGdlb19qc29uX2EwY2EwNDkzNjMyYzQ5YzZhMGI5MTllMmY4N2E5NjQzX2hpZ2hsaWdodGVyKGZlYXR1cmUpIHsKICAgICAgICAgICAgc3dpdGNoKGZlYXR1cmUuaWQpIHsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsiY29sb3IiOiAiZ3JlZW4iLCAiZGFzaEFycmF5IjogIjUsIDUiLCAiZmlsbENvbG9yIjogIiNmZmFmMDAiLCAid2VpZ2h0IjogM307CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gZ2VvX2pzb25fYTBjYTA0OTM2MzJjNDljNmEwYjkxOWUyZjg3YTk2NDNfb25FYWNoRmVhdHVyZShmZWF0dXJlLCBsYXllcikgewogICAgICAgICAgICBsYXllci5vbih7CiAgICAgICAgICAgICAgICBtb3VzZW91dDogZnVuY3Rpb24oZSkgewogICAgICAgICAgICAgICAgICAgIGdlb19qc29uX2EwY2EwNDkzNjMyYzQ5YzZhMGI5MTllMmY4N2E5NjQzLnJlc2V0U3R5bGUoZS50YXJnZXQpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG1vdXNlb3ZlcjogZnVuY3Rpb24oZSkgewogICAgICAgICAgICAgICAgICAgIGUudGFyZ2V0LnNldFN0eWxlKGdlb19qc29uX2EwY2EwNDkzNjMyYzQ5YzZhMGI5MTllMmY4N2E5NjQzX2hpZ2hsaWdodGVyKGUudGFyZ2V0LmZlYXR1cmUpKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIH0pOwogICAgICAgIH07CiAgICAgICAgdmFyIGdlb19qc29uX2EwY2EwNDkzNjMyYzQ5YzZhMGI5MTllMmY4N2E5NjQzID0gTC5nZW9Kc29uKG51bGwsIHsKICAgICAgICAgICAgICAgIG9uRWFjaEZlYXR1cmU6IGdlb19qc29uX2EwY2EwNDkzNjMyYzQ5YzZhMGI5MTllMmY4N2E5NjQzX29uRWFjaEZlYXR1cmUsCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgc3R5bGU6IGdlb19qc29uX2EwY2EwNDkzNjMyYzQ5YzZhMGI5MTllMmY4N2E5NjQzX3N0eWxlciwKICAgICAgICB9KTsKCiAgICAgICAgZnVuY3Rpb24gZ2VvX2pzb25fYTBjYTA0OTM2MzJjNDljNmEwYjkxOWUyZjg3YTk2NDNfYWRkIChkYXRhKSB7CiAgICAgICAgICAgIGdlb19qc29uX2EwY2EwNDkzNjMyYzQ5YzZhMGI5MTllMmY4N2E5NjQzCiAgICAgICAgICAgICAgICAuYWRkRGF0YShkYXRhKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF9kMDdiOTY4MjIxZGI0NDVjOTY2Y2NmNmY4YmQ0YTRlNCk7CiAgICAgICAgfQogICAgICAgICAgICBnZW9fanNvbl9hMGNhMDQ5MzYzMmM0OWM2YTBiOTE5ZTJmODdhOTY0M19hZGQoeyJmZWF0dXJlcyI6IFt7Imdlb21ldHJ5IjogeyJjb29yZGluYXRlcyI6IFtbLTIuNzE5MTY3LCA1MS4zODI3NzhdLCBbLTIuNzM2MTExLCA1MS4zODI3NzhdLCBbLTIuNzg3MjIyLCA1MS4zODIyMjJdLCBbLTIuODM4MzMzLCA1MS4zODE5NDRdLCBbLTIuODY2Mzg5LCA1MS4zNjYxMTFdLCBbLTIuODk0NzIyLCA1MS4zNTAyNzhdLCBbLTIuOTk4MDU2LCA1MS4yOTI1XSwgWy0zLjM1OTcyMiwgNTEuMTc4NjExXSwgWy0zLjM2Mjc3OCwgNTEuMTYxMTExXSwgWy0zLjM3MTk0NCwgNTEuMTA4ODg5XSwgWy0zLjM4NDE2NywgNTEuMDM5MTY3XSwgWy0zLjM4ODYxMSwgNTEuMDEzMDU2XSwgWy0zLjM5ODA1NiwgNTAuOTU3Nzc4XSwgWy0zLjQxNjk0NCwgNTAuODQ3NV0sIFstMy40MjM4ODksIDUwLjgwOTE2N10sIFstMy40MzE5NDQsIDUwLjc2MTY2N10sIFstMy40NDgzMzMsIDUwLjY2NjY2N10sIFstMy40NTI1LCA1MC42NDEzODldLCBbLTMuNDYzODg5LCA1MC41NzQxNjddLCBbLTMuNDczMzMzLCA1MC41MTg2MTFdLCBbLTMuNDkzNjExLCA1MC4zOTg2MTFdLCBbLTMuNDk1NTU2LCA1MC4zNjI3NzhdLCBbLTMuNTA1Mjc4LCA1MC4xODQxNjddLCBbLTMuNTE3MjIyLCA0OS45NjA1NTZdLCBbLTMuNTI5NDQ0LCA0OS43MzcyMjJdLCBbLTMuNTU4MzMzLCA0OS42NTg2MTFdLCBbLTMuNjM4NjExLCA0OS40NF0sIFstMy43MjgzMzMsIDQ5LjE5NTI3OF0sIFstMy43ODMwNTYsIDQ5LjA0Njk0NF0sIFstMy44MDg2MTEsIDQ4Ljk3Njk0NF0sIFstNC4wNjE2NjcsIDQ4LjMwMTk0NF0sIFstNC4xODQ3MjIsIDQ3Ljk1NzIyMl0sIFstNC4zMTI1LCA0Ny44Mjk0NDRdLCBbLTQuNTI0NzIyLCA0Ny41OTEzODldLCBbLTQuOTkwNTU2LCA0Ny4wNzkxNjddLCBbLTUuNDA4MDU2LCA0Ni42MTI3NzhdLCBbLTYuOTE5NzIyLCA0NC44MzUyNzhdLCBbLTcuMDEyNzc4LCA0NC42OTgwNTZdLCBbLTcuMTQzODg5LCA0NC41MDQ0NDRdLCBbLTguOTI2NjY3LCA0MS44NzI3NzhdLCBbLTkuMDE2MTExLCA0MS42Njc3NzhdLCBbLTkuMTYxMzg5LCA0MS4zMzQ0NDRdLCBbLTEwLjIzNDQ0NCwgMzguODczMzMzXSwgWy0xMS40NDgzMzMsIDM1Ljk2NjY2N10sIFstMTIuOTExNjY3LCAzNC4yNjExMTFdLCBbLTEzLjgzNjExMSwgMzMuMTQ5NDQ0XSwgWy0xNS4zMDE2NjcsIDMxLjMwMDgzM10sIFstMTUuODUwMjc4LCAzMC40MzM4ODldLCBbLTE2LjM3Mjc3OCwgMjkuNTkxMzg5XSwgWy0xNi45OTA1NTYsIDI4LjkyODA1Nl0sIFstMTcuMDIzMDU2LCAyOC44OTMzMzNdLCBbLTE3LjA5NDQ0NCwgMjguODE2Mzg5XSwgWy0xNy4yMTE2NjcsIDI4LjY5MDgzM10sIFstMTcuMjYzNjExLCAyOC42MzVdLCBbLTE3LjMxNTU1NiwgMjguNTc5MTY3XSwgWy0xNy4zNzQxNjcsIDI4LjUxNjM4OV0sIFstMTcuNDM5MTY3LCAyOC40NDYzODldLCBbLTE3LjQ1MjIyMiwgMjguNDMyNV0sIFstMTcuMzc1Mjc4LCAyOC4zODk0NDRdLCBbLTE3LjI5LCAyOC4zNDE2NjddLCBbLTE3LjE5NjExMSwgMjguMjg5MTY3XSwgWy0xNy4xNzA1NTYsIDI4LjI3NDcyMl0sIFstMTcuMTE1LCAyOC4yMzQ0NDRdLCBbLTE3LjAyNzc3OCwgMjguMTcwODMzXSwgWy0xNi44NzcyMjIsIDI4LjA2MTM4OV0sIFstMTYuNzczMDU2LCAyOC4wMjg4ODldLCBbLTE2LjY4Nzc3OCwgMjguMDAyNV0sIFstMTYuNjc2Mzg5LCAyOC4wMDY2NjddLCBbLTE2LjY0NzIyMiwgMjguMDE3MjIyXSwgWy0xNi42MjIyMjIsIDI4LjAyNjM4OV0sIFstMTYuNjA0MTY3LCAyOC4wMzMwNTZdLCBbLTE2LjU3MjUsIDI4LjA0NDQ0NF1dLCAidHlwZSI6ICJMaW5lU3RyaW5nIn0sICJpZCI6ICIwIiwgInR5cGUiOiAiRmVhdHVyZSJ9XSwgInR5cGUiOiAiRmVhdHVyZUNvbGxlY3Rpb24ifSk7CgogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2FmMGFiOWJmOGY2MTQ4NjQ5ZmNhNTMzMWI3NmFlZjMzID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85YTM5ZDAwOTA1MjU0OWRjOWM0NzE3MGRhYmU0YjkyMCA9ICQoYDxkaXYgaWQ9Imh0bWxfOWEzOWQwMDkwNTI1NDlkYzljNDcxNzBkYWJlNGI5MjAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlBsYWNlX0JyaXN0b2xfX19MdWxzZ2F0ZSBQbGFjZV9UZW5lcmlmZVN1cl9SZWluYVNvZmlhX0FpcnBvcnQ8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYWYwYWI5YmY4ZjYxNDg2NDlmY2E1MzMxYjc2YWVmMzMuc2V0Q29udGVudChodG1sXzlhMzlkMDA5MDUyNTQ5ZGM5YzQ3MTcwZGFiZTRiOTIwKTsKICAgICAgICAKCiAgICAgICAgZ2VvX2pzb25fYTBjYTA0OTM2MzJjNDljNmEwYjkxOWUyZjg3YTk2NDMuYmluZFBvcHVwKHBvcHVwX2FmMGFiOWJmOGY2MTQ4NjQ5ZmNhNTMzMWI3NmFlZjMzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgIGZ1bmN0aW9uIGdlb19qc29uXzY4NWY1NzkwMjc1YzQzY2NhNjU1MWRjNzJlZmJjMzcxX3N0eWxlcihmZWF0dXJlKSB7CiAgICAgICAgICAgIHN3aXRjaChmZWF0dXJlLmlkKSB7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiB7ImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogIjUsIDUiLCAiZmlsbENvbG9yIjogIiNmZmFmMDAiLCAid2VpZ2h0IjogMS41fTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBnZW9fanNvbl82ODVmNTc5MDI3NWM0M2NjYTY1NTFkYzcyZWZiYzM3MV9oaWdobGlnaHRlcihmZWF0dXJlKSB7CiAgICAgICAgICAgIHN3aXRjaChmZWF0dXJlLmlkKSB7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiB7ImNvbG9yIjogImdyZWVuIiwgImRhc2hBcnJheSI6ICI1LCA1IiwgImZpbGxDb2xvciI6ICIjZmZhZjAwIiwgIndlaWdodCI6IDN9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGdlb19qc29uXzY4NWY1NzkwMjc1YzQzY2NhNjU1MWRjNzJlZmJjMzcxX29uRWFjaEZlYXR1cmUoZmVhdHVyZSwgbGF5ZXIpIHsKICAgICAgICAgICAgbGF5ZXIub24oewogICAgICAgICAgICAgICAgbW91c2VvdXQ6IGZ1bmN0aW9uKGUpIHsKICAgICAgICAgICAgICAgICAgICBnZW9fanNvbl82ODVmNTc5MDI3NWM0M2NjYTY1NTFkYzcyZWZiYzM3MS5yZXNldFN0eWxlKGUudGFyZ2V0KTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBtb3VzZW92ZXI6IGZ1bmN0aW9uKGUpIHsKICAgICAgICAgICAgICAgICAgICBlLnRhcmdldC5zZXRTdHlsZShnZW9fanNvbl82ODVmNTc5MDI3NWM0M2NjYTY1NTFkYzcyZWZiYzM3MV9oaWdobGlnaHRlcihlLnRhcmdldC5mZWF0dXJlKSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICB9KTsKICAgICAgICB9OwogICAgICAgIHZhciBnZW9fanNvbl82ODVmNTc5MDI3NWM0M2NjYTY1NTFkYzcyZWZiYzM3MSA9IEwuZ2VvSnNvbihudWxsLCB7CiAgICAgICAgICAgICAgICBvbkVhY2hGZWF0dXJlOiBnZW9fanNvbl82ODVmNTc5MDI3NWM0M2NjYTY1NTFkYzcyZWZiYzM3MV9vbkVhY2hGZWF0dXJlLAogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHN0eWxlOiBnZW9fanNvbl82ODVmNTc5MDI3NWM0M2NjYTY1NTFkYzcyZWZiYzM3MV9zdHlsZXIsCiAgICAgICAgfSk7CgogICAgICAgIGZ1bmN0aW9uIGdlb19qc29uXzY4NWY1NzkwMjc1YzQzY2NhNjU1MWRjNzJlZmJjMzcxX2FkZCAoZGF0YSkgewogICAgICAgICAgICBnZW9fanNvbl82ODVmNTc5MDI3NWM0M2NjYTY1NTFkYzcyZWZiYzM3MQogICAgICAgICAgICAgICAgLmFkZERhdGEoZGF0YSkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfZDA3Yjk2ODIyMWRiNDQ1Yzk2NmNjZjZmOGJkNGE0ZTQpOwogICAgICAgIH0KICAgICAgICAgICAgZ2VvX2pzb25fNjg1ZjU3OTAyNzVjNDNjY2E2NTUxZGM3MmVmYmMzNzFfYWRkKHsiZmVhdHVyZXMiOiBbeyJnZW9tZXRyeSI6IHsiY29vcmRpbmF0ZXMiOiBbWy0wLjQ4MTY2NywgMzkuNDg5NDQ0XSwgWy0wLjQ5MjIyMiwgMzkuNDkzNjExXSwgWy0wLjUzNDE2NywgMzkuNTEwNTU2XSwgWy0wLjU3NjM4OSwgMzkuNTI3MjIyXSwgWy0wLjU2NjExMSwgMzkuNTMxMzg5XSwgWy0wLjUwNDcyMiwgMzkuNTU1ODMzXSwgWy0wLjQ1MzYxMSwgMzkuNTc2MTExXSwgWy0wLjM4MTk0NCwgMzkuNjA0NzIyXSwgWy0wLjM0MDgzMywgMzkuNjIxMTExXSwgWy0wLjIyODMzMywgMzkuNjY2MTExXSwgWy0wLjIwNzc3OCwgMzkuNjc0MTY3XSwgWy0wLjA0NTI3OCwgMzkuODAxOTQ0XSwgWy0wLjAwNDcyMiwgMzkuODMzODg5XSwgWzAuMDQ2OTQ0LCAzOS44NzA4MzNdLCBbMC4xNSwgMzkuOTQ0NDQ0XSwgWzAuMjcwMjc4LCA0MC4wMzA1NTZdLCBbMC40MDc3NzgsIDQwLjEyODg4OV0sIFswLjU2MjUsIDQwLjIzOTcyMl0sIFswLjU4ODMzMywgNDAuMjU4MDU2XSwgWzAuODg4MzMzLCA0MC40NjkxNjddLCBbMS4wMDMwNTYsIDQwLjU0OTcyMl0sIFsxLjA2MjIyMiwgNDAuNTkwODMzXSwgWzEuMjMxNjY3LCA0MC43MDg2MTFdLCBbMS4yNTgwNTYsIDQwLjcyNjk0NF0sIFsxLjQ1MTk0NCwgNDAuODYwODMzXSwgWzEuNTA1ODMzLCA0MC44OTc3NzhdLCBbMS43MzAyNzgsIDQxLjA1MTM4OV0sIFsxLjg1MzA1NiwgNDEuMTM0NzIyXSwgWzIuMTA3Nzc4LCA0MS4zMDcyMjJdLCBbMy4xODcyMjIsIDQxLjQ5NDQ0NF0sIFszLjQ4ODYxMSwgNDEuNTQ0NzIyXSwgWzMuODYwMjc4LCA0MS42MDU1NTZdLCBbNC42NjY2NjcsIDQxLjczMzMzM10sIFs1LjAxMzMzMywgNDEuODFdLCBbNS4zOTYzODksIDQyLjE1Nzc3OF0sIFs1LjcwOTcyMiwgNDIuNDM4MzMzXSwgWzYuMTgwMjc4LCA0Mi44NTM2MTFdLCBbNi42MDE5NDQsIDQzLjIxOTQ0NF0sIFs2Ljg0MTY2NywgNDMuMzQ2MTExXSwgWzYuODkzMzMzLCA0My4zNzMzMzNdLCBbNy4yMywgNDMuNTQ5MTY3XSwgWzcuMzcxMTExLCA0My42MjIyMjJdLCBbNy42MzI3NzgsIDQzLjc1Njk0NF0sIFs3LjY1MzA1NiwgNDMuNzY3NV0sIFs3Ljc1NTI3OCwgNDMuODE5NDQ0XSwgWzguMjIxMTExLCA0NC4wNTYxMTFdLCBbOC44MDM2MTEsIDQ0LjEzNDcyMl0sIFs5LjA1NDcyMiwgNDQuMTk0NzIyXSwgWzkuNTk0MTY3LCA0NC4zMjE2NjddLCBbMTAuMTYyNSwgNDQuNDg0MTY3XSwgWzEwLjgyMjIyMiwgNDQuNjcyNzc4XSwgWzEyLjI4MTM4OSwgNDUuMDcxMTExXSwgWzEyLjY0OTcyMiwgNDUuMDMyNzc4XSwgWzEyLjgwMTk0NCwgNDUuMDE2OTQ0XSwgWzEzLjA5MTM4OSwgNDQuOTg1ODMzXSwgWzEzLjkxODA1NiwgNDQuODkyNV0sIFsxNC44NzYxMTEsIDQ0LjcwNzIyMl0sIFsxNS41MzMwNTYsIDQ0LjU3NV0sIFsxNi4xNDMzMzMsIDQ0LjQ0ODMzM10sIFsxNi4zMDU1NTYsIDQ0LjQxMzg4OV0sIFsxNi41OTM4ODksIDQ0LjM1MTk0NF0sIFsxNi44MTYzODksIDQ0LjMwMzYxMV0sIFsxNy42NjEzODksIDQ0LjExNTgzM10sIFsxOS4xMDUsIDQ0LjU5NjM4OV0sIFsxOS4yMjM4ODksIDQ0LjYwNTgzM10sIFsxOS4zNjI3NzgsIDQ0LjYxNjk0NF0sIFsyMC43NzY2NjcsIDQ0LjcyMjc3OF0sIFsyMS4xNjk0NDQsIDQ0Ljc0ODg4OV0sIFsyMS41MzMzMzMsIDQ0Ljc3MTY2N10sIFsyMi42MTA1NTYsIDQ0Ljc3ODYxMV0sIFsyMy40NDg4ODksIDQ0Ljc3MjIyMl0sIFsyMy41MTI1LCA0NC43NzE2NjddLCBbMjMuNjUyMjIyLCA0NC43NzA4MzNdLCBbMjMuODgwODMzLCA0NC43Njg4ODldLCBbMjMuOTgyNSwgNDQuNzY4MzMzXSwgWzI0LjIxMTExMSwgNDQuNzY2Mzg5XSwgWzI0LjQ5MDU1NiwgNDQuNzY0NDQ0XSwgWzI0LjY0MzA1NiwgNDQuNzYzMzMzXSwgWzI0LjY2ODMzMywgNDQuNzYzMDU2XSwgWzI0Ljc4MjIyMiwgNDQuNzYwODMzXSwgWzI1LjE2MTM4OSwgNDQuNzUzODg5XSwgWzI1LjQyMzg4OSwgNDQuNjMyNV0sIFsyNS41NSwgNDQuNTc0MTY3XSwgWzI1LjYyMzYxMSwgNDQuNTQwMjc4XSwgWzI1LjY5ODMzMywgNDQuNTQ1Mjc4XSwgWzI1LjgyMzA1NiwgNDQuNTUzNjExXSwgWzI1LjkyMjc3OCwgNDQuNTYwMjc4XSwgWzI2LjA4NSwgNDQuNTcxMTExXV0sICJ0eXBlIjogIkxpbmVTdHJpbmcifSwgImlkIjogIjAiLCAidHlwZSI6ICJGZWF0dXJlIn1dLCAidHlwZSI6ICJGZWF0dXJlQ29sbGVjdGlvbiJ9KTsKCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMTEyMjhiN2Q5NjUxNGJiNmI0MDI3ZGQ5ODJhOTExN2EgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2NhNjVlMjg2YjEzMTRhNzdhMjIyMDgzYTdlODdmYTBiID0gJChgPGRpdiBpZD0iaHRtbF9jYTY1ZTI4NmIxMzE0YTc3YTIyMjA4M2E3ZTg3ZmEwYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UGxhY2VfVmFsZW5jaWFfTWFuaXNlc19BaXJwb3J0IFBsYWNlX0J1Y3VyZXN0aV9IZW5yaUNvYW5kYV9BaXJwb3J0PC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzExMjI4YjdkOTY1MTRiYjZiNDAyN2RkOTgyYTkxMTdhLnNldENvbnRlbnQoaHRtbF9jYTY1ZTI4NmIxMzE0YTc3YTIyMjA4M2E3ZTg3ZmEwYik7CiAgICAgICAgCgogICAgICAgIGdlb19qc29uXzY4NWY1NzkwMjc1YzQzY2NhNjU1MWRjNzJlZmJjMzcxLmJpbmRQb3B1cChwb3B1cF8xMTIyOGI3ZDk2NTE0YmI2YjQwMjdkZDk4MmE5MTE3YSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGxheWVyX2NvbnRyb2xfYTI2MWQ1MDk2MTRlNDA3ZGE0ODBmZmRkMDAxOTE0MzAgPSB7CiAgICAgICAgICAgICAgICBiYXNlX2xheWVycyA6IHsKICAgICAgICAgICAgICAgICAgICAib3BlbnN0cmVldG1hcCIgOiB0aWxlX2xheWVyXzUxYWJlNjczMGYxYTRlZGY5NjE1NTliM2UyNzY1MmZiLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG92ZXJsYXlzIDogIHsKICAgICAgICAgICAgICAgICAgICAiUGxhY2VfTW9udHBlbGxpZXJNZWRpdGVycmFuZWVfQWlycG9ydFBsYWNlX0Jhc3RpYVBvcmV0dGFfQWlycG9ydCIgOiBnZW9fanNvbl9mNjE0YTc3OGM4ZWU0ZjA1YmI0YjVlNDg1NTMxNGRjZCwKICAgICAgICAgICAgICAgICAgICAiUGxhY2VfQnJpc3RvbF9fX0x1bHNnYXRlUGxhY2VfVGVuZXJpZmVTdXJfUmVpbmFTb2ZpYV9BaXJwb3J0IiA6IGdlb19qc29uX2EwY2EwNDkzNjMyYzQ5YzZhMGI5MTllMmY4N2E5NjQzLAogICAgICAgICAgICAgICAgICAgICJQbGFjZV9WYWxlbmNpYV9NYW5pc2VzX0FpcnBvcnRQbGFjZV9CdWN1cmVzdGlfSGVucmlDb2FuZGFfQWlycG9ydCIgOiBnZW9fanNvbl82ODVmNTc5MDI3NWM0M2NjYTY1NTFkYzcyZWZiYzM3MSwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIEwuY29udHJvbC5sYXllcnMoCiAgICAgICAgICAgICAgICBsYXllcl9jb250cm9sX2EyNjFkNTA5NjE0ZTQwN2RhNDgwZmZkZDAwMTkxNDMwLmJhc2VfbGF5ZXJzLAogICAgICAgICAgICAgICAgbGF5ZXJfY29udHJvbF9hMjYxZDUwOTYxNGU0MDdkYTQ4MGZmZGQwMDE5MTQzMC5vdmVybGF5cywKICAgICAgICAgICAgICAgIHsiYXV0b1pJbmRleCI6IHRydWUsICJjb2xsYXBzZWQiOiB0cnVlLCAicG9zaXRpb24iOiAidG9wcmlnaHQifQogICAgICAgICAgICApLmFkZFRvKG1hcF9kMDdiOTY4MjIxZGI0NDVjOTY2Y2NmNmY4YmQ0YTRlNCk7CiAgICAgICAgCjwvc2NyaXB0Pg== onload=\"this.contentDocument.open();this.contentDocument.write(atob(this.getAttribute('data-html')));this.contentDocument.close();\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
      ],
      "text/plain": [
       "<folium.folium.Map at 0x7f831cb550d0>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import folium\n",
    "\n",
    "\n",
    "m = folium.Map(location=[40, 10], zoom_start=4, control_scale=True, prefer_canvas=True)\n",
    "\n",
    "\n",
    "def style_function(feature):\n",
    "    return {\"fillColor\": \"#ffaf00\", \"color\": \"blue\", \"weight\": 1.5, \"dashArray\": \"5, 5\"}\n",
    "\n",
    "\n",
    "def highlight_function(feature):\n",
    "    return {\"fillColor\": \"#ffaf00\", \"color\": \"green\", \"weight\": 3, \"dashArray\": \"5, 5\"}\n",
    "\n",
    "\n",
    "for index, row in df.iterrows():\n",
    "    c = folium.GeoJson(\n",
    "        row[\"geojson\"],\n",
    "        name=(\"{}{}\".format(row[\"dep\"], row[\"dest\"])),\n",
    "        overlay=True,\n",
    "        style_function=style_function,\n",
    "        highlight_function=highlight_function,\n",
    "    )\n",
    "    folium.Popup(\"{}\\n{}\".format(row[\"dep\"], row[\"dest\"])).add_to(c)\n",
    "    c.add_to(m)\n",
    "\n",
    "folium.LayerControl().add_to(m)\n",
    "\n",
    "m"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
